/**
 * 
 */
package com.hpe.business.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.sf.json.JSONObject;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.hpe.business.dao.tickets.ITicketMapper;
import com.hpe.business.qo.TicketReportQo;
import com.hpe.business.service.ITicketsReportService;
import com.hpe.business.vo.TicketReportVo;
import com.hpe.core.enums.ChannelsEnum;
import com.hpe.core.utils.DateUtils;
import com.hpe.core.utils.ReportUtils;

/**
 * 车票统计服务接口实现类
 * @author luolin
 *
 * @version $id:TicketsReportServiceImpl.java,v 0.1 2016年1月8日 下午4:52:11 luolin Exp $
 */
@Service("ticketsReportService")
public class TicketsReportServiceImpl implements ITicketsReportService {

    /** 日志 */
    private static final Logger LOGGER = Logger.getLogger(TicketsReportServiceImpl.class);
    /** 车票持久层服务接口 */
    @Resource
    private ITicketMapper       ticketMapper;

    /* 
     * 售票总量统计
     * @see com.hpe.bsslink.service.ITicketsReportService#ticketsTotalReport(com.hpe.bsslink.qo.TicketReportQo)
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<List<TicketReportVo>> ticketsTotalReport(TicketReportQo qo) {

        LOGGER.info("【售票总量统计】qo = " + JSONObject.fromObject(qo));

        // 计算时间节点（按 天/周/月 划分）
        Map<String, Object> datePoint = ReportUtils.datePointCut(qo.getDateBegin(), qo.getDateEnd());

        // 日期切片类型
        String datePointType = (String) datePoint.get(DateUtils.DATE_POINT_TYPE);

        // 封装通用的查询参数
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("datePointType", datePointType);
        param.put("station", qo.getStationCode());

        List<String> dates = (List<String>) datePoint.get(DateUtils.DATE_POINT_RESULT);
        // 得到处理后的时间切片的起止日期
        String dateBegin = dates.get(0);
        String dateEnd = dates.get(dates.size() - 1);

        // 渠道
        List<String> channels = Arrays.asList(qo.getSysChannel().split(","));
        List<List<TicketReportVo>> dataList = new ArrayList<List<TicketReportVo>>();
        for (String channel : channels) {
            if (ChannelsEnum.TOTAL.getCode().equals(channel)) {
                continue;
            }
            param.put("channel", channel);
            param.put("dateBegin", dateBegin);
            param.put("dateEnd", dateEnd);
            LOGGER.info("【统计参数】param = " + param);
            List<TicketReportVo> results = ticketMapper.queryTotalReportData(param);
            // 对结果进行处理，在时间节点上，没有值的数据填充为0
            dataList.add(fillNullData(results, dates, channel));
        }

        if (channels.contains(ChannelsEnum.TOTAL.getCode())) {
            // 统计每个时间节点的售票总量（所选渠道在时间节点上售票总量之和）
            List<TicketReportVo> totalTickets = queryTotalTickets(
                (List<String>) datePoint.get(DateUtils.DATE_POINT_RESULT), datePointType, qo);
            dataList.add(totalTickets);
        }

        return dataList;
    }

    /**
     * 对结果进行处理，在时间节点上，没有值的数据填充为0
     * @param results 数据库查询出来的数据
     * @param dates 时间节点集合
     * @param channel 渠道
     * @return 填充完整数据后的{@link TicketReportVo}集合
     * @Author : luolin. create at 2015年12月23日 下午2:47:37
     */
    private List<TicketReportVo> fillNullData(List<TicketReportVo> results, List<String> dates, String channel) {
        LOGGER.info("【处理统计数据】channel = " + channel);
        Map<String, TicketReportVo> map = list2Map(results);

        List<TicketReportVo> reports = new ArrayList<TicketReportVo>();
        // 查询的数据集为空
        if (MapUtils.isEmpty(map)) {
            for (String date : dates) {
                reports.add(new TicketReportVo(date, 0, channel, null));
            }
            return reports;
        }

        // 查询出来的数据集不为空
        for (String date : dates) {
            reports.add(map.get(date) != null ? map.get(date) : new TicketReportVo(date, 0, channel, null));
        }

        return reports;
    }

    /**
     * 将list转换成map
     * @param list 要转换成map的集合对象
     * @return 转换后的map对象
     * @Author : luolin. create at 2015年12月23日 下午2:52:12
     */
    private Map<String, TicketReportVo> list2Map(List<TicketReportVo> list) {
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        Map<String, TicketReportVo> map = new HashMap<String, TicketReportVo>();
        for (TicketReportVo result : list) {
            map.put(result.getDate(), result);
        }
        return map;
    }

    /**
     * 统计每个时间节点的售票总量（所选渠道在时间节点上售票总量之和）
     * @param datePoint 时间节点
     * @param datePointType 时间节点类型
     * @param qo {@link TicketReportQo}
     * @return 售票总量统计数据
     * @Author : luolin. create at 2015年12月22日 下午3:56:15
     */
    private List<TicketReportVo> queryTotalTickets(List<String> datePoint, String datePointType, TicketReportQo qo) {
        LOGGER.info("【统计每个时间节点的售票总量（所选渠道在时间节点上售票总量之和）】");
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("station", qo.getStationCode());
        param.put("datePointType", datePointType);
        List<String> channels = Arrays.asList(qo.getSysChannel().split(","));
        param.put("channels", channels);

        List<TicketReportVo> totalTickets = new ArrayList<TicketReportVo>();
        for (String date : datePoint) {
            param.put("date", date);
            LOGGER.info("【参数】param = " + param);
            TicketReportVo vo = ticketMapper.queryTotalTickets(param);
            vo.setDate(date);
            vo.setChannel(ChannelsEnum.TOTAL.getCode());
            totalTickets.add(vo);
        }
        return totalTickets;
    }

}
